package it.uniroma2.svd;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import it.uniroma2.svd.StreamGobbler;


public class ExecSVD {
	private int _lsadim;
	private String _outpath;
	private String _inputfile;
	private String _svdExec;
	private boolean binary_input = true;
	private boolean binary_output = true;
	
	public ExecSVD(){
		_svdExec = "lib/lsa/linux_x86_64/svd";
	}
	
	public ExecSVD(int lsadim , String _outBaseDir,String smtx) {
		_lsadim = lsadim;
		_inputfile = _outBaseDir+File.separator+smtx;
		_outpath = _outBaseDir+File.separator+lsadim+File.separator;
		_svdExec = "lib/lsa/linux_x86_64/svd";
		
	}

	public void ExecSVDFromPath(int lsadim , String _outBaseDir,String pathSmtx){
		_lsadim = lsadim;
		_inputfile = pathSmtx;
		_outpath = _outBaseDir+File.separator+lsadim+File.separator;
		_svdExec = "lib/lsa/linux_x86_64/svd";
		
	}

	public ExecSVD(int lsadim,File _outBaseDir,File smtx, boolean _binary_input, boolean _binary_output){
		binary_input = _binary_input; 
		binary_output = _binary_output; 
		_lsadim = lsadim;
		_inputfile = smtx.getAbsolutePath();
		_outpath = _outBaseDir.getAbsolutePath()+File.separator+lsadim+File.separator;
		_svdExec = "lib/lsa/linux_x86_64/svd";
		
	}

	
	public void transposeMatrix(String inputFile){
		CmdExec(_svdExec+" -r sb -w sb -t "+" -c "+inputFile+" "+inputFile+"_T");
	}
	
	public void runSVD(){
		File _outDir = new File(_outpath);
		if(_outDir.exists() ){
			if(!_outDir.delete()){
				for(File file : _outDir.listFiles()){
					file.delete();
				}
			}
		}
		_outDir.mkdirs();
		CmdExec(_svdExec+" -r " + (binary_input?"db":"dt") +" -w " + (binary_output?"db":"dt") +" -d "+_lsadim+" -o "+_outpath+"svd "+_inputfile);
		File svdS = new File(_outpath+"svd-S");
		if(!svdS.exists()){
			CmdExec(_svdExec+" -r " + (binary_input?"db":"dt") +" -w " + (binary_output?"db":"dt") +" -d "+_lsadim+" -o "+_outpath+"svd "+_inputfile +"_T");
		}
	}
	
	
//	private void CmdExec(String cmdline) {
//		try {
//			System.out.println("Execute "+cmdline);
//			Process p = Runtime.getRuntime().exec(cmdline);
//			p.waitFor();
//		}catch (Exception err) {
//			err.printStackTrace();
//		}
//	}
//	
	
	public static void CmdExec(String cmdline) {
		try {
			//String commandLine[] = {"/bin/sh","-c",cmdline};		
			String commandLine[] = {"/bin/sh","-c",cmdline};			
			System.out.println("Execute /bin/sh -c "+cmdline);
			Process p = Runtime.getRuntime().exec(commandLine);

			BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
			String input_line = reader.readLine();
			while (input_line!=null) {
				System.out.println("SVD OUTPUT : " + input_line);
				input_line = reader.readLine();
			}
			int exit = p.waitFor();
			System.out.println("Exit value: "+ exit);
	
			
			 StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "ERROR");             
//			 // any output?
//			 StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(), "OUTPUT");
//			 // kick them off
			 errorGobbler.start();
//			 outputGobbler.start();
//			
//			p.waitFor();
			//	p.destroy();
			
		}catch (Exception err) {
			err.printStackTrace();
		}
	}
	
	
	
}

	/*
	 * 
	 * QUESTO THREAD CONSENTE DI LEGGERE E STAMPARE SU STANDARD OUTPUT GLI STREAM STANDARD
	 * DI OUTPUT O DI ERRORE GENERATI DURANTE L'ESECUZIONE DEL PROGRAMMA
	 * LANCIATO MEDIANTE LA FUNZIONE exec()
	 * 
	 * */
	class StreamGobbler extends Thread 	{
	    InputStream is;
	    String type;
	    StreamGobbler(InputStream is, String type)
	    {
	        this.is = is;
	        this.type = type;
	    }
	    
	    public void run()
	    {
	        try
	        {
	            InputStreamReader isr = new InputStreamReader(is);
	            BufferedReader br = new BufferedReader(isr);
	            String line=null;
	            while ( (line = br.readLine()) != null)
	            {
	            	if(type.equalsIgnoreCase("error"))
	            		System.out.println(type + " : " + line);
	            	else
	            		System.out.println(line);	
	            }
	            } catch (IOException ioe)
	              {
	                ioe.printStackTrace();  
	              }
	    }

	
	}  // end class StreamGobbler




